import { _ } from "@atinc/chaos";
import { inject, injectable } from "@atinc/chaos/container";
import { UserRepository } from "../../repository/user.repository";
import { Sex, UserEntity } from "../../entity/user.entity";
import { OperationDescription } from "@atinc/chaos/repository";
import { CreateUserRequest, GetUserRequest, UpdateUserRequest } from "./request";
import { OperationContext, RouterContext } from "@atinc/chaos/router";
import { WTInvalidInputError } from "@atinc/chaos/errors";
import { PagenationRequest } from "@atinc/chaos/repository/pagenation-calculator";
import { FindByPageIndexResult } from "@atinc/chaos/repository/find-by-page-index-result";

@injectable()
export class UserService {
    @inject()
    public userRepository!: UserRepository;

    private readonly op: OperationDescription = new OperationDescription("test", _.createId(), _.createId().toString());

    public async getAllUsers(ctx: RouterContext<OperationContext>): Promise<UserEntity[]> {
        return this.userRepository.findAll();
    }

    public async getUser(ctx: RouterContext<OperationContext>, request: GetUserRequest): Promise<Partial<UserEntity>> {
        return this.userRepository.findOneById(OperationDescription.from(ctx.operationContext), request.id, {}, {
            includes: {
                deleted: request.deleted,
                archived: request.archived
            }
        });
    }

    public async getUsers(ctx: RouterContext<OperationContext>, page: PagenationRequest): Promise<FindByPageIndexResult<UserEntity>> {
        const condition = {};
        return this.userRepository.findByPageIndex(OperationDescription.from(ctx.operationContext), condition, page.pageIndex, page.pageSize);

    }

    public async createUser(ctx: RouterContext<OperationContext>, request: CreateUserRequest): Promise<UserEntity> {
        const userEntity = new UserEntity();
        userEntity.username = request.username;
        userEntity.sex = Sex[request.sex];
        userEntity.password = request.password;
        return await this.userRepository.insertOne(this.op, userEntity) as Promise<UserEntity>;
    }

    public async updateUser(ctx: RouterContext<OperationContext>, request: UpdateUserRequest): Promise<UserEntity> {
        const userEntity = await this.userRepository.findOneById(OperationDescription.from(ctx.operationContext), request.id);
        if (userEntity === undefined) {
            throw new WTInvalidInputError("用户不存在", 400);
        }
        userEntity.username = request.username;
        userEntity.sex = Sex[request.sex];
        userEntity.password = request.password;
        return await this.userRepository.insertOne(this.op, userEntity) as Promise<UserEntity>;
    }


}
